import * as types from './../mutation-types'
import elementUiLocale from 'element-ui/lib/locale'
import Utils from '@/utils/Utils.js'
import config from '@/global/config.js'

// const zhCN = require('@/assets/js/localization/zh-CN.json')
// const en = require('@/assets/js/localization/en.json')
// const fr = require('@/assets/js/localization/fr.json') // 法国
// const ja = require('@/assets/js/localization/ja.json') // 日本
// const nl = require('@/assets/js/localization/nl.json') // 荷兰
// const ko = require('@/assets/js/localization/ko.json') // 韩国
// const vi = require('@/assets/js/localization/vi.json') // 越南

let langRequires = {
  'zh-CN': (resolve) => {
    require.ensure([], () => {
      resolve(require('@/assets/js/localization/zh-CN.json'))
    })
  },
  'zh-Hant': (resolve) => {
    require.ensure([], () => {
      resolve(require('@/assets/js/localization/zh-Hant.json'))
    })
  },
  'en': (resolve) => {
    require.ensure([], () => {
      resolve(require('@/assets/js/localization/en.json'))
    })
  },
  'fr': (resolve) => {
    require.ensure([], () => {
      resolve(require('@/assets/js/localization/fr.json'))
    })
  },
  'ja': (resolve) => {
    require.ensure([], () => {
      resolve(require('@/assets/js/localization/ja.json'))
    })
  },
  'nl': (resolve) => {
    require.ensure([], () => {
      resolve(require('@/assets/js/localization/nl.json'))
    })
  },
  'ko': (resolve) => {
    require.ensure([], () => {
      resolve(require('@/assets/js/localization/ko.json'))
    })
  },
  'vi': (resolve) => {
    require.ensure([], () => {
      resolve(require('@/assets/js/localization/vi.json'))
    })
  }
}
let replacedLang = {}
// 替换整个语言包
function replaceLang (lang, langKey) {
  // 只替换一次
  if (replacedLang[langKey]) return

  for (let key in lang) {
    lang[key] = Utils.replaceText(lang[key], 'siteName', config.siteName)
    lang[key] = Utils.replaceText(lang[key], 'mailDomain', config.mailDomain)
    lang[key] = Utils.replaceText(lang[key], 'siteAddress', config.siteAddress)
  }
  replacedLang[langKey] = true
}

// 先加载一个默认语言包
const defaultLangKey = config.defaultLang
let defaultLang = require(`@/assets/js/localization/${defaultLangKey}.json`)

// 根据config替换lang变量
replaceLang(defaultLang, defaultLangKey)

let currentLangKey = localStorage.getItem('langKey')
if (currentLangKey) {
  getLang(currentLangKey).then((res) => {
    langList[currentLangKey] = res

    // 根据config替换lang变量
    replaceLang(langList[currentLangKey], currentLangKey)

    state.lang = langList[currentLangKey]
    state.langKey = currentLangKey
    elementUiLocale.use(state.lang['element-ui'])
  })
} else {
  currentLangKey = defaultLangKey
}

let langList = {
  'zh-CN': defaultLangKey === 'zh-CN' ? defaultLang : null,
  'zh-Hant': defaultLangKey === 'zh-Hant' ? defaultLang : null,
  'en': defaultLangKey === 'en' ? defaultLang : null,
  'fr': defaultLangKey === 'fr' ? defaultLang : null,
  'ja': defaultLangKey === 'ja' ? defaultLang : null,
  'nl': defaultLangKey === 'nl' ? defaultLang : null,
  'ko': defaultLangKey === 'ko' ? defaultLang : null,
  'vi': defaultLangKey === 'vi' ? defaultLang : null,
}
const state = {
  lang: defaultLang,
  langKey: currentLangKey
}
elementUiLocale.use(state.lang['element-ui'])

function getLang (key) {
  let p = Utils.makePromise()
  langRequires[key](p.resolveHandle)
  return p
}

// 存储语言文本，lang一开始给对象（包括vue实例）的变量赋值，切换语言后就不再自动切换语种了
const langTextList = {}
const switchLangText = (oldLangKey, newLangKey) => {
  for (let key in langTextList) {
    let textParams = langTextList[key]
    // 只有被lang赋过值的model才赋值，不然就会破坏原程序变量和逻辑
    for (let i = 0; i < textParams.vm.length; i++) { // 相同key可能有多个vm
      if (textParams.vm[i] && textParams.vm[i][textParams.modelKey] === langList[oldLangKey][textParams.langTextKey]) {
        textParams.vm[i][textParams.modelKey] = state.lang[textParams.langTextKey]
      }
    }
  }
}

const getters = {
  lang: state => state.lang,
  langKey: state => state.langKey
}

const mutations = {
  [types.SWITCH_LANG] (state, language) {
    let oldLangKey = state.langKey
    let newLandKey = language

    state.lang = langList[newLandKey]
    state.langKey = newLandKey

    switchLangText(oldLangKey, newLandKey)

    // elementui语言切换
    elementUiLocale.use(state.lang['element-ui'])

    localStorage.setItem('langKey', language)
  },
  [types.DEFINE_LANG_TEXT] (state, params) {
    params.vm[params.modelKey] = state.lang[params.langTextKey]
    // 考虑到key相同但vm不同的情况，故vm要变成数组
    let key = params.modelKey + '-' + params.langTextKey
    let textParams = langTextList[key]
    if (!textParams) {
      langTextList[key] = {
        vm: [params.vm],
        modelKey: params.modelKey,
        langTextKey: params.langTextKey
      }
    } else {
      textParams.vm.push(params.vm)
    }
  }
}

const actions = {
  switchLang ({ commit }, language) { // arguments是context，通过context.state访问局部state，全局是state
    if (langList[language]) {
      commit(types.SWITCH_LANG, language)
    } else {
      getLang(language)
      .then((res) => {
        // 根据config替换lang变量
        replaceLang(res, language)

        langList[language] = res
        commit(types.SWITCH_LANG, language)
      })
    }
  },
  defineLangText ({ commit }, params) {
    commit(types.DEFINE_LANG_TEXT, params)
  }
}

export default {
  state,
  getters,
  mutations,
  actions
}
